#include "tcp_client.h"

TcpClient::TcpClient(QTcpSocket *socket, QObject *parent) : QObject(parent)
{
    this->m_socket = socket;
    m_ip = socket->peerAddress().toString();
    m_ip = m_ip.replace("::ffff:", "");
    m_port = socket->peerPort();


    connect(m_socket, &QAbstractSocket::errorOccurred, this, &TcpClient::disconnected);
    connect(socket, &QTcpSocket::disconnected, this, &TcpClient::disconnected);
    connect(socket, &QTcpSocket::readyRead, this, &TcpClient::readData);

    //connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(disconnected()));
    // connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    // connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
}


QString TcpClient::byteArrayToHexStr(const QByteArray &data)
{
    QString tmp = "";
    QString hex = data.toHex();

    for(int i = 0; i < hex.length();i += 1){
        tmp += hex.mid(i ,2) + " ";
    }

    return tmp.trimmed().toUpper();
}

QByteArray TcpClient::hexStrToByteArray(const QString &data)
{
    QByteArray senddata;
    int hexdata, lowhexdata;
    int hexdatalen = 0;
    int len = data.length();
    senddata.resize(len / 2);
    char lstr, hstr;

    for (int i = 0; i < len;) {
        hstr = data.at(i).toLatin1();
        if (hstr == ' ') {
            i++;
            continue;
        }

        i++;
        if (i >= len) {
            break;
        }

        lstr = data.at(i).toLatin1();
        hexdata = hexStrToChar(hstr);
        lowhexdata = hexStrToChar(lstr);

        if ((hexdata == 16) || (lowhexdata == 16)) {
            break;
        } else {
            hexdata = hexdata * 16 + lowhexdata;
        }

        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }

    senddata.resize(hexdatalen);
    return senddata;
}

char TcpClient::hexStrToChar(char data)
{
    if ((data >= '0') && (data <= '9')) {
        return data - 0x30;
    } else if ((data >= 'A') && (data <= 'F')) {
        return data - 'A' + 10;
    } else if ((data >= 'a') && (data <= 'f')) {
        return data - 'a' + 10;
    } else {
        return (-1);
    }
}

QMap<char, QString> listChar;
void initAsciiStr()
{
    //0x20为空格,空格以下都是不可见字符
    if (listChar.count() == 0) {
        listChar.insert(0, "\\NUL");
        listChar.insert(1, "\\SOH");
        listChar.insert(2, "\\STX");
        listChar.insert(3, "\\ETX");
        listChar.insert(4, "\\EOT");
        listChar.insert(5, "\\ENQ");
        listChar.insert(6, "\\ACK");
        listChar.insert(7, "\\BEL");
        listChar.insert(8, "\\BS");
        listChar.insert(9, "\\HT");
        listChar.insert(10, "\\LF");
        listChar.insert(11, "\\VT");
        listChar.insert(12, "\\FF");
        listChar.insert(13, "\\CR");
        listChar.insert(14, "\\SO");
        listChar.insert(15, "\\SI");
        listChar.insert(16, "\\DLE");
        listChar.insert(17, "\\DC1");
        listChar.insert(18, "\\DC2");
        listChar.insert(19, "\\DC3");
        listChar.insert(20, "\\DC4");
        listChar.insert(21, "\\NAK");
        listChar.insert(22, "\\SYN");
        listChar.insert(23, "\\ETB");
        listChar.insert(24, "\\CAN");
        listChar.insert(25, "\\EM");
        listChar.insert(26, "\\SUB");
        listChar.insert(27, "\\ESC");
        listChar.insert(28, "\\FS");
        listChar.insert(29, "\\GS");
        listChar.insert(30, "\\RS");
        listChar.insert(31, "\\US");
        listChar.insert(0x5C, "\\");
        listChar.insert(0x7F, "\\DEL");
    }
}

QString TcpClient::decimalToStrHex(int decimal)
{
    QString temp = QString::number(decimal, 16);
    if (temp.length() == 1) {
        temp = "0" + temp;
    }

    return temp;
}

int TcpClient::strHexToDecimal(const QString &strHex)
{
    bool ok;
    return strHex.toInt(&ok, 16);
}


QString TcpClient::byteArrayToAsciiStr(const QByteArray &data)
{
    initAsciiStr();
    QString temp;
    int len = data.size();

    for (int i = 0; i < len; i++) {
        char byte = data.at(i);
        QString value = listChar.value(byte);
        if (!value.isEmpty()) {
        } else if (byte >= 0 && byte <= 0x7F) {
            value = QString("%1").arg(byte);
        } else {
            value = decimalToStrHex((quint8)byte);
            value = QString("\\x%1").arg(value.toUpper());
        }

        temp += value;
    }

    return temp.trimmed();
}

QByteArray TcpClient::asciiStrToByteArray(const QString &data)
{
    initAsciiStr();
    QByteArray buffer;
    QStringList list = data.split("\\");

    int count = list.count();
    for (int i = 1; i < count; i++) {
        QString str = list.at(i);
        int key = 0;
        if (str.contains("x")) {
            key = strHexToDecimal(str.mid(1, 2));
        } else {
            key = listChar.key("\\" + str);
        }

        buffer.append(key);
    }

    return buffer;
}


QString TcpClient::getIP() const
{
    return this->m_ip;
}

int TcpClient::getPort() const
{
    return this->m_port;
}

void TcpClient::disconnected()
{
    m_socket->deleteLater();
    this->deleteLater();
    emit clientDisconnected();
}

void TcpClient::readData()
{



    QByteArray data = m_socket->readAll();

    if (data.length() <= 0) {
        return;
    }

    // if(data.mid(0,2).toHex().toUpper() != QString("FFD8")){
    //     qDebug()<<"帧头正确";
    // }else{
    //     qDebug()<<"帧头正确";
    // }

    qDebug()<<"收到的原始数据:"<<data;

    //QString buffer = byteArrayToHexStr(data);
    QString buffer = byteArrayToAsciiStr(data);

    qDebug()<<"转换格式之后的数据"<<buffer;

    emit receiveData(m_ip, m_port, buffer);
}

void TcpClient::sendData(const QString &data)
{
    QByteArray buffer = hexStrToByteArray(data);
    //QByteArray buffer = asciiStrToByteArray(data);

    qDebug()<<"实际发送的数据："<<buffer;
    m_socket->write(buffer);
    emit sendData(m_ip, m_port, data);
}

void TcpClient::abort()
{
    m_socket->abort();
}
